package com.zrrd.yunchmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrrd.yunchmall.product.entity.*;
import com.zrrd.yunchmall.product.mapper.ProductMapper;
import com.zrrd.yunchmall.product.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 商品信息 服务实现类
 * </p>
 *
 * @author LiYe
 * @since 2024-01-15
 */
@SuppressWarnings("all")
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    @Autowired
    private IProductAttributeValueService attributeValueService;
    @Autowired
    private IMemberPriceService memberPriceService;
    @Autowired
    private IProductLadderService ladderService;
    @Autowired
    private IProductFullReductionService fullReductionService;
    @Autowired
    private ISkuStockService skuStockService;
    /**
     * 重写mybatis-plus中的save方法
     */
    @Override
    @Transactional
    @SuppressWarnings("all")
    public boolean save(Product product) {
        //1. 保存商品信息
        super.save(product);
        //2. 保存商品属性值信息 productAttributeValueList
        List<ProductAttributeValue> productAttributeValueList = product.getProductAttributeValueList();
        productAttributeValueList.forEach(item -> {
            item.setProductId(product.getId());//设置商品ID
        });
        attributeValueService.saveBatch(productAttributeValueList); //将所有项批量添加
        //3. 保存商品会员价格信息 memberPriceList
        List<MemberPrice> memberPriceList = product.getMemberPriceList();
        memberPriceList.forEach(item -> {
            item.setProductId(product.getId());//设置商品ID
        });
        memberPriceService.saveBatch(memberPriceList);
        //4. 保存折扣信息 productLadderList
        List<ProductLadder> productLadderList = product.getProductLadderList();
        productLadderList.forEach(item -> {
            item.setProductId(product.getId());//设置商品ID
        });
        ladderService.saveBatch(productLadderList);
        //5. 满减信息 productFullReductionList
        List<ProductFullReduction> productFullReductionList = product.getProductFullReductionList();
        productFullReductionList.forEach(item -> {
            item.setProductId(product.getId());//设置商品ID
        });
        fullReductionService.saveBatch(productFullReductionList);
        //6. 增加SKU库存信息
        List<SkuStock> skuStockList = product.getSkuStockList();
        String skuCodePrefix = System.currentTimeMillis() + "";
        for (int i=0; i<skuStockList.size(); i++) {
            skuStockList.get(i).setProductId(product.getId());
            String x = i < 10 ? ("0"+i) : (""+i);
            skuStockList.get(i).setSkuCode(skuCodePrefix + x);
        }
        skuStockService.saveBatch(skuStockList);
        //7. 保存商品信息操作日志
//        ProductOperateLog operateLog = new ProductOperateLog();
        return true;
    }

    @Autowired
    private IProductCategoryService productCategoryService;

    @Override
    public Product detail(Serializable id) {
        Product product = super.getById(id);
        if (product == null) return null;
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select("parent_id");
        queryWrapper.eq("id", product.getProductCategoryId());
        product.setCateParentId((Long) productCategoryService.listObjs(queryWrapper).get(0));
        queryWrapper = new QueryWrapper();
        queryWrapper.eq("product_id", id);
        product.setMemberPriceList(memberPriceService.list(queryWrapper));
//        System.out.println(product.getCateParentId() + "---------------------------------------");
        return product;
    }
    /*
    [
        {"productId": 1, "skuId": 3, "quantity":2},
        {"productId": 2, "skuId": 15, "quantity":1}
        {"productId": 8, "skuId": 104, "quantity":10}
    ]
     */
    @Override
    @Transactional
    public void freeStock(List<Map<String, Long>> params) {
        //遍历params
        params.forEach(item -> {
            Long productId = item.get("productId");
            Long skuId = item.get("skuId");
            Long quantity = item.get("quantity");
            UpdateWrapper updateWrapper = new UpdateWrapper();
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.select("stock");
            queryWrapper.eq("id", productId);
            int stock = super.getOne(queryWrapper).getStock();
            // 用当前库存 + 释放的库存量 进行更新
            updateWrapper.set("stock", stock + quantity);
            updateWrapper.eq("id", productId);
            //更新商品表库存
            super.update(updateWrapper);
            updateWrapper.clear();
            queryWrapper.clear();
            queryWrapper.select("stock");
            queryWrapper.eq("id", skuId);
            // 用当前库存 + 释放的库存量 进行更新
            stock = skuStockService.getOne(queryWrapper).getStock();
            updateWrapper.set("stock", stock + quantity);
            updateWrapper.eq("id", skuId);
            //更新sku表库存
            skuStockService.update(updateWrapper);
        });
    }
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    //这个分页查询数据源是ES
    @Override
    public Page page(String keyword, Integer publishStatus, Integer verifyStatus, String productSn, Integer productCategoryId, Integer brandId, int pageNum, int pageSize) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //设置排序规则，根据id属性排序
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("id"));
        //针对关键词进行全文查询
        if (!StringUtils.isEmpty(keyword)) {
            MultiMatchQueryBuilder multiMatchQueryBuilder
                    = QueryBuilders.multiMatchQuery(keyword, "name", "sub_title", "brand_name", "description", "keywords");
            nativeSearchQueryBuilder.withQuery(multiMatchQueryBuilder);
        }
        //针对其他属性进行精确检索
        if (publishStatus != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("publish_status", publishStatus);
            nativeSearchQueryBuilder.withQuery(termQueryBuilder);
        }
        if (verifyStatus != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("verify_status", verifyStatus);
            nativeSearchQueryBuilder.withQuery(termQueryBuilder);
        }
        if (!StringUtils.isEmpty(productSn)) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("product_sn", productSn);
            nativeSearchQueryBuilder.withQuery(termQueryBuilder);
        }
        if (productCategoryId != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("product_category_id", productCategoryId);
            nativeSearchQueryBuilder.withQuery(termQueryBuilder);
        }
        if (brandId != null) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brand_id", brandId);
            nativeSearchQueryBuilder.withQuery(termQueryBuilder);
        }
        //设置分页
        PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
        nativeSearchQueryBuilder.withPageable(pageRequest);
        //查询结果
        SearchHits<Product> searchHits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Product.class);
        Page page = new Page();
        page.setTotal(searchHits.getTotalHits());//总共条数
        page.setSize(pageRequest.getPageSize());//每页条数
        long pages = searchHits.getTotalHits() % pageRequest.getPageSize() == 0 ? //判断是否能够整除
                searchHits.getTotalHits() / pageRequest.getPageSize() : //整除直接返回商
                searchHits.getTotalHits() / pageRequest.getPageSize() + 1; //无法整除返回商+1
        page.setPages(pages);//总共几页
        page.setCurrent(pageRequest.getPageNumber() + 1);
        //设置查询列表
        List<Product> records = new LinkedList<>();
        searchHits.forEach(item -> {
            records.add(item.getContent());
        });
        page.setRecords(records);
        return page;
    }
}
